﻿namespace ExtensionMethods
{
    using System;
    using System.Collections;
    using System.Collections.Generic;

    public static class MainExtensionMethods
    {
        //// 1.2.16.02. Implement a set of extension methods for IEnumerable<T> that implement the
        //// following group functions: sum, product, min, max, average.

        public static void PrintCollection(this IEnumerable collection)
        {
            foreach (var element in collection)
            {
                Console.WriteLine(element);
            }
        }

        public static void Separator()
        {
            Console.WriteLine(new string('-', 20));
        }

        public static void Sum<T>(this IEnumerable<T> collection, T addition)
        {
            dynamic result = collection; // it's a reference so whatever we change in result will affect and collection; I make new variable because when I foreach collection I can't assign values to its
            
            int index = 0;

            foreach (var element in collection)
            {
                result[index] = (T)((dynamic)element + (dynamic)addition);
                index++;
            }
        }

        public static void Product<T>(this IEnumerable<T> collection, T addition)
        {
            dynamic result = collection;

            int index = 0;

            foreach (var element in collection)
            {
                result[index] = (T)((dynamic)element * (dynamic)addition);
                index++;
            }
        }

        public static T Min<T>(this IEnumerable<T> collection)
        {
            dynamic dynCollection = collection; // I need it because I can use indexes only for dynamics

            T min = dynCollection[0];

            foreach (var element in collection)
            {
                if ((dynamic)element < (dynamic)min)
                {
                    min = element;
                }
            }

            return min;
        }

        public static T Max<T>(this IEnumerable<T> collection)
        {
            dynamic dynCollection = collection; // I need it because I can use indexes for dynamics

            T max = dynCollection[0];

            foreach (var element in collection)
            {
                if ((dynamic)element > (dynamic)max)
                {
                    max = element;
                }
            }

            return max;
        }

        public static T Average<T>(this IEnumerable<T> collection)
        {
            dynamic sum = 0;

            int index = 0;

            foreach (var element in collection)
            {
                sum += element;
                index++;
            }

            return sum / index;
        }

        private static void Main()
        {
            int[] example = { 1, 2, 3 };
            example.PrintCollection();

            Separator();

            example.Sum<int>(2);
            example.PrintCollection();

            Separator();

            example.Product<int>(2);
            example.PrintCollection();

            Separator();

            Console.WriteLine(example.Min<int>());

            Separator();

            Console.WriteLine(example.Max<int>());

            Separator();

            Console.WriteLine(example.Average<int>());
        }
    }
}